package soria.cabinet.security;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class AES {
    private static final String ALGORITHM = "AES";
    private static final String PATTERN = "AES/ECB/PKCS5Padding";

    /**
     * 初始化AES密钥
     *
     * @return AES密钥
     */
    protected static String generateKey() {
        byte[] MAC = Device.getMAC();
        StringBuilder stringBuilderMAC = new StringBuilder();
        stringBuilderMAC.append("sora");
        for (byte b : MAC) {
            stringBuilderMAC.append(Integer.toHexString(b & 0xff));
        }
        return String.valueOf(stringBuilderMAC);
    }

    /**
     * 获取AES密钥规范
     *
     * @param key 密钥
     * @return 密钥规范
     */
    private static SecretKeySpec getSecretKeySpec(String key) {
        byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
        return new SecretKeySpec(keyBytes, ALGORITHM);
    }

    /**
     * AES加密
     *
     * @param data 需要加密的内容
     * @param key  密钥
     * @return 加密后的内容
     */
    protected static byte[] encrypt(byte[] data, String key) {
        try {
            //创建AES加密器
            Cipher cipher = Cipher.getInstance(PATTERN);
            SecretKeySpec secretKeySpec = getSecretKeySpec(key);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            //加密字节数组
            byte[] encryptedBytes = cipher.doFinal(data);
            //将密文转换为 Base64 编码字符串并返回
            return Base64.getEncoder().encode(encryptedBytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * AES解密
     *
     * @param data 需要解密的文本内容
     * @param key  解密的密钥 key
     */
    protected static byte[] decrypt(byte[] data, String key) {
        //将密文转换为16字节的字节数组
        byte[] dataBytes = Base64.getDecoder().decode(data);
        try {
            //创建AES解密器
            Cipher cipher = Cipher.getInstance(PATTERN);
            SecretKeySpec secretKeySpec = getSecretKeySpec(key);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            //解密字节数组并返回
            return cipher.doFinal(dataBytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
